﻿using System.Collections.Generic;
using UnityEngine;

public class GroundChecker : UnitTerrainCheckerBase
{
    /// <summary>
    /// 是否接触地面
    /// </summary>
    public bool isGround { get; set; }

    /// <summary>
    /// 当前接触地面
    /// </summary>
    public GroundInfo currentGroundInfo { get; set; }

    /// <summary>
    /// 碰撞箱
    /// </summary>
    public BoxCollider2D colliBox
    {
        get
        {
            if (m_ColliBox == null)
            {
                m_ColliBox = GetComponent<BoxCollider2D>();
                m_ColliBox.isTrigger = false;
            }
            return m_ColliBox;
        }
    }
    private BoxCollider2D m_ColliBox;

    public bool canJumpAcross => currentGroundInfo != null && currentGroundInfo.canJumpAcross;

    private RaycastHit2D[] m_Hit2DLeft, m_Hit2DRight;
    private List<GroundInfo> m_GroundInfos = new List<GroundInfo>();

    protected override void UpdateTerrainInfo(long _)
    {
        // 在碰撞体的左右两端分别向下发射一段射线
        var offset = Vector3.right * colliBox.size.x * 0.5f;
        // Ground碰撞体检测
        m_Hit2DLeft = Physics2D.RaycastAll(transform.position - offset, Vector2.down, 0.1f, layers);
        m_Hit2DRight = Physics2D.RaycastAll(transform.position + offset, Vector2.down, 0.1f, layers);
        m_GroundInfos.Clear();
        foreach (var hit2d in m_Hit2DLeft)
        {
            var groundInfo = hit2d.collider.GetComponent<GroundInfo>();
            if (groundInfo == null && m_GroundInfos.Contains(groundInfo)) continue;
            m_GroundInfos.Add(groundInfo);
        }
        foreach (var hit2d in m_Hit2DRight)
        {
            var groundInfo = hit2d.collider.GetComponent<GroundInfo>();
            if (groundInfo == null && m_GroundInfos.Contains(groundInfo)) continue;
            m_GroundInfos.Add(groundInfo);
        }
        // 更新isGround值
        isGround = m_GroundInfos.Count > 0;
        // 更新当前地形
        if (isGround)
        {
            m_GroundInfos.Sort(GroundInfoSortRule);
            currentGroundInfo = m_GroundInfos[0];
        }
        else
        {
            currentGroundInfo = null;
        }
    }

    private int GroundInfoSortRule(GroundInfo x, GroundInfo y)
    {
        return x.groundType.CompareTo(y.groundType);
    }
}